package com.edev.support.ddd.join;

import com.edev.support.entity.Entity;

import java.io.Serializable;
import java.util.Collection;

/**
 * 实体关联关系操作接口（聚合根模式）
 * <p>
 * 核心职责：处理实体间所有的关联关系及其相关操作，包括：
 * 1. 插入和更新实体时，如果它们之间有聚合关系，要联级操作所有子实体，并保证数据的一致性
 * 2. 删除实体时，如果它们之间有聚合关系，要级联删除所有关联的子实体，并保证数据的一致性
 * 3. 加载实体时，要同时加载所有与其关联的子实体，最终形成一个完整的实体对象
 * <p>
 * 泛型参数：
 * @param <E> 实体类型（需继承Entity）
 * @param <S> 序列化主键类型
 */
public interface Relation<E extends Entity<S>, S extends Serializable> {
    /**
     * 插入实体的同时，要插入所有与其有聚合关系实体，并保证操作的原子性。
     * <p>
     * 执行逻辑：
     * 1. 插入主实体
     * 2. 级联插入所有聚合关系的子实体
     * 3. 保证操作原子性
     * @param entity 主实体对象（携带有聚合关系的子实体）
     */
    void insertValue(E entity);

    /**
     * 更新实体的同时，要更新所有有聚合关系的子实体，并保证操作的原子性。
     * <p>
     * 注意：
     * - 要先比较提交的关联子实体，与数据库中的关联子实体是否有变化
     * - 根据比较觉得对子实体的新增/修改/删除操作
     * - 保证实体与子实体操作的原子性
     * @param entity 主实体对象（携带有聚合关系的子实体）
     */
    void updateValue(E entity);

    /**
     * 删除实体的同时，删除所有有聚合关系的子实体，并保证操作的原子性。
     * <p>
     * 执行逻辑：
     * 1. 删除主实体
     * 2. 级联删除所有聚合子实体    
     * 3. 保证操作的原子性
     * @param entity 主实体对象
     */
    void deleteValue(E entity);

    /**
     * 装配实体时，查找并装配所有有关联关系的子实体。
     * @param entity 主实体对象
     */
    void setValue(E entity);

    /**
     * 批量装配实体集合的同时，查找并装配所有有关联关系的子实体。
     * <p>
     * 优化策略：
     * - 批量装配实体集合时，批量查找需要装配的所有关联子实体，避免频繁的数据库查询
     * - 然后根据子实体的关联键，将子实体集合进行分组，完成最终的实体装配
     * @param list 主实体集合
     */
    void setValueForList(Collection<E> list);
}
